package com.gc.frontend.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.ClientProtocolException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gc.gpsoo.GpsooSDK;
import com.gc.gpsoo.beans.GpsooCarData;
import com.gc.gpsoo.beans.GpsooDevData;
import com.gc.gpsoo.exception.GpsooSDKException;
import com.gc.common.dto.CarDTO;
import com.gc.common.entity.Car;
import com.gc.common.exception.ServiceException;
import com.gc.common.mapper.AlertMapper;
import com.gc.common.mapper.CarMapper;
import com.gc.common.mapper.HistoryMapper;
import com.gc.common.mapper.HistoryPositionBusinessMapper;
import com.gc.frontend.service.CarService;

/**
 * 
 * @author 章瑱彬 
 * 电话：15914921094
 * QQ：562800930
 * @since 2015年3月23日
 */
@Service
public class CarServiceImpl implements CarService {

	@Autowired
	private CarMapper carMapper;

	@Autowired
	private HistoryMapper historyMapper;

	@Autowired
	private HistoryPositionBusinessMapper historyPositionBusinessMapper;

	@Autowired
	private AlertMapper alertMapper;
	
	@Override
	public int deleteByPrimaryKey(Integer id) {
		return this.carMapper.deleteByPrimaryKey(id);
	}

	@Override
	public int deleteInIds(String ids) {
		//删除要把相应的Hitory和Alert记录删掉，不为什么，爽！
		this.historyPositionBusinessMapper.deleteInCarIds(ids);
		this.historyMapper.deleteInCarImeis(ids);
		this.alertMapper.deleteInCarImeis(ids);
		return this.carMapper.deleteInIds(ids);
	}

	@Override
	public int insert(Car record) {
		return this.carMapper.insert(record);
	}

	@Override
	public int insertSelective(Car record) {
		return this.carMapper.insertSelective(record);
	}

	@Override
	public Car selectByPrimaryKey(Integer id) {
		return this.carMapper.selectByPrimaryKey(id);
	}

	@Override
	public int updateByPrimaryKeySelective(Car record) {
		return this.carMapper.updateByPrimaryKeySelective(record);
	}

	@Override
	public int updateByPrimaryKey(Car record) {
		return this.carMapper.updateByPrimaryKey(record);
	}

	@Override
	public List<Car> selectByDTO(CarDTO dto) {
		return this.carMapper.selectByDTO(dto);
	}

	@Override
	public List<Map<String, Object>> selectFront(Integer carId) {
		return this.carMapper.selectFront(carId);
	}


	@Override
	public int insertList(List<Car> cars) {
		return this.carMapper.insertList(cars);
	}

	private List<GpsooCarData> getCarsInGpsoo() throws ServiceException {
		List<GpsooCarData> gpsooDatasMap;
		try {
			GpsooSDK gpsooSDK = GpsooSDK.getInstance();
			gpsooDatasMap = gpsooSDK.loadMonitor();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			throw new ServiceException("网络连接错误！");
		} catch (IOException e) {
			e.printStackTrace();
			throw new ServiceException("数据读取错误");
		} catch (GpsooSDKException e) {
			e.printStackTrace();
			throw new ServiceException(e.getMessage());
		}
		return gpsooDatasMap;
	}

	private List<GpsooDevData> getDevsInGpsoo() throws ServiceException {
		List<GpsooDevData> gpsooDevsMap;
		try {
			GpsooSDK gpsooSDK = GpsooSDK.getInstance();
			gpsooDevsMap = gpsooSDK.loadDevinfo();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			throw new ServiceException("网络连接错误！");
		} catch (IOException e) {
			e.printStackTrace();
			throw new ServiceException("数据读取错误");
		} catch (GpsooSDKException e) {
			e.printStackTrace();
			throw new ServiceException(e.getMessage());
		}
		return gpsooDevsMap;
	}

	@Override
	public JSONObject synchronizeWithGpsoo() throws ServiceException {
		List<Car> carsInDb = selectByDTO(null);
		List<GpsooDevData> carsInGpsoo = getDevsInGpsoo();

		Map<String, Car> carsInDbWithKey = new HashMap<String, Car>();
		Map<String, GpsooDevData> carsInGpsooWithKey = new HashMap<String, GpsooDevData>();

		//增加Key，通过键值表来拿检索，时间复杂度为O(n)
		for (Car car : carsInDb) {
			carsInDbWithKey.put(car.getCarImei(), car);
		}
		for (GpsooDevData gpsooCarData : carsInGpsoo) {
			carsInGpsooWithKey.put(gpsooCarData.getImei(), gpsooCarData);
		}


		//服务器没有的数据...我们删除他好了
		Iterator<String> carImeiInteger = carsInDbWithKey.keySet().iterator();
		String carImei;
		List<Integer> deleteCarIds = new ArrayList<Integer>();
		while (carImeiInteger.hasNext()) {
			carImei = carImeiInteger.next();
			if (carsInGpsooWithKey.get(carImei) == null) {
				deleteCarIds.add(carsInDbWithKey.get(carImei).getCarId());
			}
		}

		//服务器多出来的我们插入，已经有的看看有没有更新
		Iterator<String> carsInGpsooImeiIterator = carsInGpsooWithKey.keySet().iterator();
		String carInGpsooImei;
		List<Car> updateCars = new ArrayList<Car>();
		List<Car> insertCars = new ArrayList<Car>();

		while (carsInGpsooImeiIterator.hasNext()) {
			carInGpsooImei = carsInGpsooImeiIterator.next();
			GpsooDevData devInfo = carsInGpsooWithKey.get(carInGpsooImei);
			if (carsInDbWithKey.get(carInGpsooImei) == null) {
				Car carToInsert = new Car();
				carToInsert.setCarImei(carInGpsooImei);
				carToInsert.setCarNum(devInfo.getNumber());
				carToInsert.setLrrq(new Date());
				carToInsert.setLrry("后台同步");
				insertCars.add(carToInsert);
			} else {
				Car car = carsInDbWithKey.get(carInGpsooImei);
				if (!car.getCarNum().equals(devInfo.getNumber())) {
					Car carToUpdate = new Car();
					carToUpdate.setCarId(car.getCarId());
					carToUpdate.setCarNum(devInfo.getNumber());
					updateCars.add(carToUpdate);
				}
			}
		}

		JSONObject resultObject = new JSONObject();

		StringBuilder idsSb = new StringBuilder("");
		for (Integer id : deleteCarIds) {
			idsSb.append(id + ",");
		}
		if (idsSb.length() > 0) {
			idsSb.deleteCharAt(idsSb.length() - 1);
			String deleteCarIdsStr = idsSb.toString();
			deleteInIds(deleteCarIdsStr);
			resultObject.put("delete", deleteCarIds);
		}
		if (insertCars.size() > 0) {
			insertList(insertCars);
			resultObject.put("insert", insertCars);
		}
		if (updateCars.size() > 0) {
			updateList(updateCars);
			resultObject.put("update", updateCars);
		}
		return resultObject;
	}

	@Override
	public int updateList(List<Car> cars) {
		int i = 0;
		for (Car car : cars) {
			i++;
			this.carMapper.updateByPrimaryKeySelective(car);
		}
		return i;
	}


}

